package com.nx.platform.es.biz.esspider.expression;

import org.antlr.v4.runtime.*;
import org.jetbrains.annotations.Nullable;

import java.util.function.Consumer;

/**
 * @author
 * @date Oct 25, 2017
 */
public class ExpressionErrorListener extends BaseErrorListener {

    private final Consumer<String> errorMsgConsumer;

    public ExpressionErrorListener(@Nullable Consumer<String> errorMsgConsumer) {
        this.errorMsgConsumer = errorMsgConsumer;
    }

    @Override
    public void syntaxError(Recognizer<?, ?> recognizer,
                            Object offendingSymbol,
                            int line, int charPositionInLine,
                            String msg,
                            RecognitionException e) {
        if (errorMsgConsumer != null) {
            errorMsgConsumer.accept(errorMessage(recognizer, (Token) offendingSymbol, line, charPositionInLine, msg));
        }
    }

    protected String errorMessage(Recognizer recognizer,
            Token offendingToken, int line,
            int charPositionInLine,
            String msg) {
        CommonTokenStream tokens = (CommonTokenStream) recognizer.getInputStream();
        String input = tokens.getTokenSource().getInputStream().toString();
        String[] lines = input.split("\n");
        String errorLine = lines[line - 1];
        StringBuilder error = new StringBuilder();
        error.append("line ").append(line).append(':').append(charPositionInLine).append(' ').append(msg).append('\n');
        error.append(errorLine).append('\n');
        for (int i = 0; i < charPositionInLine; i++) {
            error.append(' ');
        }
        int start = offendingToken.getStartIndex();
        int stop = offendingToken.getStopIndex();
        if (start >= 0 && stop >= 0) {
            for (int i = start; i <= stop; i++) {
                error.append("^");
            }
        }
        return error.toString();
    }

}
